docs(app-shell): page-route action examples taught the unreadable nested action bag - #7894
Merged
Merged
Conversation
…ted `action` bag (objectui#7866)
`packages/app-shell/README.md` taught the `action:button` page-route
triggers as `"action": { "action": "navigate_create", ... }`. Nothing
reads that shape: `action-button.tsx:160,173` forwards
`type: schema.actionType` and `params: schema.params` and never reads
`schema.action`, so `ActionRunner.execute`'s
`action.type || action.actionType || action.name` resolves to the empty
string and no handler is dispatched.
Both examples now hoist the handler name to `actionType` with a
top-level `params`. The `navigate_edit` example additionally drops its
`"recordId": "${record.id}"`: values under `params` are never
template-evaluated (SchemaRenderer evaluates `properties`/`props`
per-value and shallowly, `content`, and the spec's bindable top-level
text keys, and `action:button` has no row in that carriage map), while
`resolveNavigateEditUrl` has no context fallback for `recordId` -- so
the template reached the handler verbatim and would have been
URL-encoded into the route.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7866
packages/app-shell/README.mdtaught the twoaction:buttonpage-route examples as a nestedactionbag. Nothing reads that shape, so both examples were inert. This is the second half of #7440's five sites — the half left standing when that card's execution surface was narrowed to the guide page.Measured on current
main(af05c88bb), not inheritedThe shape that reaches the handler — read off both ends, exact lines confirmed on this tree:
packages/components/src/renderers/action/action-button.tsx:160,173type: schema.actionTypeand...paramsPayload(built fromschema.paramsat:126-128);grepforschema.actionin that file returns zero hitspackages/core/src/actions/ActionRunner.ts:972const actionType = action.type || action.actionType || action.name || ''packages/core/src/actions/ActionRunner.ts:1064if (actionType && this.handlers.has(actionType))action.actionbagSo the authored
actionbag leavesactionTypeundefined,actionTyperesolves to'',handlers.has('')is false, and no handler is dispatched. A working authoring shape exists ⇒ documentation error, not a missing capability (the card's stop-condition was checked and not met).Fence language: both blocks are
```json— NOT the guide page's```jsoncMeasured at
:610and:618. That difference matters, and it makes the blind spot wider here than on the guide page:packages/app-shell/README.md?check:doc-typescontent/docs,apps/<app>/docs/**and the rootREADME.mdonly (stated atcheck-doc-component-types.mjs:214-220)check:doc-snippetsts/tsx/typescriptfences (:489,:874)check:doc-fencescheck:doc-expression-carriagecontent/docsonly (:452), and is report-only in CITwo-way mutation, with a live control (each mutation proven on disk by counting the injected and the removed text; each restore proven by
git hash-objectequality with theHEADblob):type→action:buttonZZin this READMEEXIT=0, counters byte-identical to baseline (188 files / 1105 blocks / 887 literals / 770 registered)navigate_createZZin this READMEEXIT=0, same byte-identical counters"type": "object-grid"→object-gridZZin the rootREADME.mdEXIT=1,README.md:272 [unregistered-doc-type], counter 770 → 769The control proves the instrument is alive; the identical counters prove the file is not in its scan population at all. ⇒ This corrects the reading inherited from #7865. On the guide page exactly one instrument read those blocks and read only the
typekey. Here zero instruments read these blocks — mutating even the componenttypeis invisible.Repair, per site — the two examples were teaching different things
:614navigate_create— mechanical. It teaches "trigger the create route, naming the object explicitly". Handler name hoisted toactionType, arguments to a top-levelparams;paramskept, because this example's whole point is supplyingobjectName.:622-625navigate_edit— needed more than a rewrite, as the card warned. Measured: it does carry a template. It authored"recordId": "${record.id}", and:paramsare never template-evaluated.SchemaRenderer.tsxevaluatesproperties/propsper-value and shallowly (:942-944, and:898-903states the shallowness),content(:1072), and the spec's bindable top-level text keys (:1139-1145) — where:1126records thataction:buttonhas no row.paramsis in none of those channels.resolveNavigateEditUrl(packages/app-shell/src/utils/recordFormNavigation.ts:300) readsaction.params?.recordId ?? action.recordIdwith no context fallback —:287says so explicitly ("record ids are intrinsically per-action").So the template would have arrived verbatim, passed the non-empty guard at
:302, and beenencodeURIComponent-ed into the route as/apps/<app>/account/record/%24%7Brecord.id%7D/edit. A merely mechanical key move would have published a second broken example that now succeeds into a garbage URL. Repaired as a literalrecordIdplus prose naming the constraint, and a pointer to the built-in per-row Edit entry point for the dynamic case — matching the shape #7440 landed for the same situation.Neither README example was demonstrating omission of the arguments, so unlike #7440's third example, neither keeps
paramsabsent.One same-sentence normalization, named here rather than left silent: the lead-in said
JSON `<action:button>` schemas. The angle-bracket form is this README's spelling for React components (<ObjectForm>,<ConsoleShell>);action:buttonis a JSON node type, spelled bare everywhere else in this file (record:approvals) and in the sibling guide. That sentence was rewritten anyway to introduceactionType.Verification
Gate union re-run on the pushed commit
a7e6f28de, withgit diff HEADempty. Exit codes captured by redirecting first, never through a pipe; each line is the gate's own verdict line.check:doc-types✅ Every documented component type is registered.check:doc-fences✅ every TypeScript block in 227 document(s) is fenced ts/tsx/typescript …docs:check-linkscheck:doc-snippetsSemantic phase: 456 of 456 block(s) judged, 0 failed.check:readme-exports✅ OK (43 tracked README(s) …, 3300 export symbol(s) read from 36 of 40 tracked package(s) …)check:control-bytes✅ OK (scanned 6388 tracked text file(s); skipped 85 binary).check-changeset-presence✅ No source or published contract of a released package changed in this range, so no changeset is owed.check-governed-queue-guard --self-testOK … 132 cases passcheck-governed-queue-guard --test packages/app-shell/README.md✅ NOT GOVERNED — 1 path(s) checked against 5 governed surface(s); none matched.check:doc-snippetsandcheck:readme-exportsboth first returned their precondition states ("PRECONDITION NOT MET (exit 2)" and "the population COLLAPSED -- this run proves nothing"), which are "I could not run", not verdicts. Both were re-run to a real green after the scoped build (turbo run build $(node scripts/check-doc-snippet-types.mjs --build-filter), 34/34 tasks, plus@object-ui/plugin-ai..., 9/9) — the builds ran through the container's shared heavy-verify lock.No changeset on the checker's verdict, quoted above — not on my reasoning.
Scope
One file:
packages/app-shell/README.md. No source line changed;action-button.tsxandActionRunner.tsare untouched.content/docs/guide/record-edit-modes.md(#7440's closed surface) is untouched.Generated by Claude Code